/*
* File: ParameterizedTaskPanel.java
* Author: Daniel Rogers
* Created on Oct 19, 2007
*
*/
package gri.tasks.gui;
import java.awt.*;
import javax.swing.*;
import gri.tasks.ParameterDef;
import java.util.Map;
import java.util.HashMap;
import gri.gui.widgets.Widget;
import gri.tasks.gui.widgets.ParameterWidgetFactory;
import dan.swing.style.AppStyles;
/**
* JPanel which displays widgets for a set of ParameterDefs. The widgets
* are created by a factory and then displayed vertically with each one
* appropriately labeled. The values of the widgets may be invoked by
* calling setValues() and getValues(). Note that such a panel can be
* used for both input and display although the default widget factory creates
* input widgets.
*
* @author dan.rogers
*/
public class ParameterPanel extends JPanel {
ParameterDef [] paramDefs;
Widget [] widgets;
int gapWidth = 4;
// ------------------------------------------------ Constructors
public ParameterPanel(ParameterDef [] params, Widget [] widgets) {
super(null);
super.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
this.paramDefs = params;
this.widgets = widgets;
update();
}
public ParameterPanel(ParameterDef [] params, ParameterWidgetFactory factory) {
super(null);
super.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
Widget [] widgets = new Widget[params.length];
for (int i=0; i<params.length; i++) {
Widget widget = factory.createWidget(params[i]);
if (widget == null)
throw new RuntimeException("No widget available for parameter: " + params[i].getName());
widgets[i] = widget;
}
this.paramDefs = params;
this.widgets = widgets;
update();
}
// ------------------------------------------------ Presentation
protected void clear() {
this.removeAll();
}
protected void update() {
clear();
if (paramDefs == null)
return;
ParameterDef paramDef;
for (int i=0; i<paramDefs.length; i++) {
paramDef = paramDefs[i];
//if (this.gapWidth > 0 && i != 0)
// this.add(Box.createVerticalStrut(this.gapWidth));
ParamPanel panel = new ParamPanel(paramDef, widgets[i]);
this.add(panel);
AppStyles.applyStyle(panel, "ParameterPanel.ParamPanel");
if (paramDef.hasDefaultValue())
widgets[i].setValue(paramDef.getDefaultValue());
}
//this.add(Box.createVerticalGlue());
}
// --------------------------------------------------- Accessors
/**
* Returns a Map containing the values of the displayed parameters
* keyed by parameter name.
*/
public Map getValues() {
Map inputs = new HashMap();
Component [] comps = super.getComponents();
for (int i=0; i<comps.length; i++) {
if (comps[i] instanceof ParamPanel) {
ParamPanel panel = (ParamPanel)comps[i];
String paramName = panel.getParameterDef().getName();
Object value = panel.getWidget().getValue();
System.out.println(paramName + " = " + value);
inputs.put(paramName, value);
}
}
return inputs;
}
/**
* Sets the values to be displayed. A map of (paramName -> value) is
* expected and the given value will be set on the appropriate widgets.
*/
public void setValues(Map values) {
//iterate over ParamPanels so we can handle absent values
Component [] comps = super.getComponents();
for (int i=0; i<comps.length; i++) {
if (comps[i] instanceof ParamPanel) {
ParamPanel panel = (ParamPanel)comps[i];
String paramName = panel.getParameterDef().getName();
//NOTE: this sets NULL for absent values
//Object value = values.get(paramName);
//panel.getWidget().setValue(value);
//NOTE: this skips absent values
if (values.containsKey(paramName)) {
Object value = values.get(paramName);
panel.getWidget().setValue(value);
}
}
}
}
/**
* Sets the given named parameter on the widget (updating the display?).
*/
public void setValue(String name, Object value) {
ParamPanel panel = getParamPanel(name);
if (panel == null)
throw new RuntimeException("Unknown parameter: " + name);
panel.getWidget().setValue(value);
}
/**
* Returns the given parameter value (as retrieved from the widget)
*/
public Object getValue(String name) {
ParamPanel panel = getParamPanel(name);
if (panel == null)
throw new RuntimeException("Unknown parameter: " + name);
return panel.getWidget().getValue();
}
protected int indexOfParam(String name) {
for (int i=0; i<paramDefs.length; i++)
if (paramDefs[i].getName().equals(name))
return i;
return -1;
}
protected ParamPanel getParamPanel(String paramName) {
int index = indexOfParam(paramName);
return index < 0 ?
null : (ParamPanel)getComponent(index);
}
// --------------------------------------------------------- Inner Classes
/**
* Panel that presents one parameter. The parameter's display name is
* given on a JLabel to the left of an object widget for the parameter's
* value.
*/
protected class ParamPanel extends JPanel {
ParameterDef param;
Widget widget;
int maxHelpLength = 60;
// --- Constructors
public ParamPanel(ParameterDef param, Widget widget) {
super(new BorderLayout());
this.param = param;
this.widget = widget;
init();
}
// --- Display
JLabel lblName;
Component widgetComp;
JLabel lblHelp;
protected void init() {
lblName = new JLabel(param.getDisplayName() + ":");
AppStyles.applyStyle(lblName, "ParameterPanel.ParamPanel label.name");
add(lblName, BorderLayout.WEST);
add(Box.createHorizontalStrut(8), BorderLayout.CENTER);
widgetComp = widget.getDisplayComponent();
add(widgetComp, BorderLayout.EAST);
lblHelp = new JLabel();
AppStyles.applyStyle(lblHelp, "ParameterPanel.ParamPanel label.help");
String description = param.getDescription();
if (description != null) {
if (description.length() <= maxHelpLength)
lblHelp.setText(description);
else {
lblHelp.setText(description.substring(0, maxHelpLength) + " ...");
lblHelp.setToolTipText(description);
}
}
add(lblHelp, BorderLayout.SOUTH);
}
// --- Accessors
public ParameterDef getParameterDef() {return this.param;}
public Widget getWidget() {return this.widget;}
}
}